package com.ruoyi.mentor.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.constant.ChooseStatusConstants;
import com.ruoyi.common.core.page.PagePlus;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.mentor.bo.ChooseAddBo;
import com.ruoyi.mentor.bo.ChooseEditBo;
import com.ruoyi.mentor.bo.ChooseQueryBo;
import com.ruoyi.mentor.bo.StudentInInstructorQueryBo;
import com.ruoyi.mentor.domain.*;
import com.ruoyi.mentor.domain.SelectedInsVo.SelectedInsVo;
import com.ruoyi.mentor.mapper.ChooseMapper;
import com.ruoyi.mentor.service.IChooseService;
import com.ruoyi.mentor.vo.*;
import com.ruoyi.mentor.vo.ExportStudentVo.ExportStudentVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.Null;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 志愿选择：学生先选，导师确认Service业务层处理
 *
 * @author LH
 * @date 2021-05-21
 */
@Service
public class ChooseServiceImpl extends ServiceImpl<ChooseMapper, Choose> implements IChooseService {

    @Autowired
    private InstructorServiceImpl instructorService;

    @Autowired
    private StudentServiceImpl studentService;

    @Autowired
    private SpotServiceImpl spotService;

    @Autowired
    private SubjectServiceImpl subjectService;

    @Autowired
    private MailServiceImpl mailService;

    @Autowired
    StudentDetailServiceImpl studentDetailService;

    @Override
    public ChooseVo queryById(Long id){
        return getVoById(id, ChooseVo.class);
    }

    @Override
    public TableDataInfo<ChooseStuInsVo> queryPageList(ChooseQueryBo bo) {
        PagePlus<Choose, ChooseVo> result = pageVo(PageUtils.buildPagePlus(), buildQueryWrapper(bo), ChooseVo.class);
        List<ChooseStuInsVo> collect = result.getRecordsVo().stream().map(item -> {
            ChooseStuInsVo chooseStuInsVo = BeanUtil.toBean(item, ChooseStuInsVo.class);
            Long stuId = item.getStuId();
            Student student = studentService.getById(stuId);
            Long insId = item.getInsId();
            Instructor instructor = instructorService.getById(insId);
            Long chooseSubId = item.getSubId();
            Subject chooseSubject = subjectService.getById(chooseSubId);
            Subject subject = subjectService.getById(student.getSubId());

            chooseStuInsVo.setStuName(student.getStuName());
            chooseStuInsVo.setSubId(subject.getId());
            chooseStuInsVo.setSubName(subject.getSubName());
            chooseStuInsVo.setChooseSubId(chooseSubject.getId());
            chooseStuInsVo.setChooseSubName(chooseSubject.getSubName());
            chooseStuInsVo.setInsId(instructor.getId());
            chooseStuInsVo.setInsName(instructor.getInsName());

            return chooseStuInsVo;
        }).collect(Collectors.toList());

        TableDataInfo<ChooseStuInsVo> tableDataInfo = new TableDataInfo<>();
        tableDataInfo.setTotal(result.getTotal());
        tableDataInfo.setMsg("查询成功");
        tableDataInfo.setCode(HttpStatus.HTTP_OK);
        tableDataInfo.setRows(collect);
        return tableDataInfo;
    }


    private LambdaQueryWrapper<Choose> buildQueryWrapper(ChooseQueryBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<Choose> lqw = Wrappers.lambdaQuery();
        lqw.eq(StrUtil.isNotBlank(bo.getYear()), Choose::getYear, bo.getYear());
        lqw.eq(bo.getRoundId()!=null, Choose::getRoundId, bo.getRoundId());
        lqw.eq(bo.getStuId()!=null, Choose::getStuId, bo.getStuId());
        lqw.eq(bo.getInsId()!=null, Choose::getInsId, bo.getInsId());
        lqw.eq(bo.getChooseSubId()!=null,Choose::getSubId,bo.getChooseSubId());
        return lqw;
    }


    private LambdaQueryWrapper<Choose> buildQueryWrapper(StudentInInstructorQueryBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<Choose> lqw = Wrappers.lambdaQuery();
        lqw.eq(Choose::getInsId,bo.getInsId());
        //只选择学生已选择的和老师确认的学生
        lqw.in(Choose::getChooseStatus, Arrays.asList(1,2));
        lqw.eq(bo.getChooseSubId()!=null,Choose::getSubId,bo.getChooseSubId());
        lqw.orderByAsc(Choose::getChooseStatus);
        lqw.orderByDesc(Choose::getSubId);
        return lqw;
    }

    @Override
    public Boolean insertByAddBo(ChooseAddBo bo) {
        Choose add = BeanUtil.toBean(bo, Choose.class);
        validEntityBeforeSave(add);
        return save(add);
    }

    @Override
    public Boolean updateByEditBo(ChooseEditBo bo) {
        Choose update = BeanUtil.toBean(bo, Choose.class);
        validEntityBeforeSave(update);
        return updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(Choose entity){
        //TODO 做一些数据校验,如唯一约束
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return removeByIds(ids);
    }

    @Override
    public List<SelectedInsVo> getInsInfoByStuId(Long stuId) {


        Choose choose = getOne(new QueryWrapper<Choose>().eq("stu_id", stuId).eq("year",Calendar.getInstance().get(Calendar.YEAR)));
        if (choose==null){
            return new ArrayList<>();
        }
        Instructor ins = instructorService.getById(choose.getInsId());
        SelectedInsVo selectedInsVo  = BeanUtil.toBean(ins,SelectedInsVo.class);
        Subject subject = subjectService.getById(choose.getSubId());
        selectedInsVo.setSubName(subject.getSubName());
        selectedInsVo.setSubId(choose.getSubId());

        return Arrays.asList(selectedInsVo);
    }

    @Override
    public TableDataInfo<InsStudentVo> getMyStudent(StudentInInstructorQueryBo bo) {
        PagePlus<Choose, ChooseVo> result = pageVo(PageUtils.buildPagePlus(), buildQueryWrapper(bo), ChooseVo.class);
        List<InsStudentVo> collect = result.getRecordsVo().stream().map(item -> {
            Long stuId = item.getStuId();
            InsStudentVo studentVo = studentService.getVoById(stuId, InsStudentVo.class);
            studentVo.setInsExamineStatus(item.getChooseStatus());
            studentVo.setChooseSubId(item.getSubId());
            return studentVo;
        }).filter(item->{
            boolean flag1 = true;
            boolean flag2 = true;
            boolean flag3 = true;
            boolean flag4 = true;
            if (bo.getStuGender()!=null){
                flag1 =  bo.getStuGender()==item.getStuGender();
            }
            if (!StrUtil.isEmpty(bo.getStuName())){
                flag2 =  item.getStuName().contains(bo.getStuName());
            }
            if (bo.getSubId()!=null){
                flag3 = bo.getSubId()-item.getSubId()==0;
            }
            return flag1&&flag2&&flag3;
        }).collect(Collectors.toList());
        TableDataInfo<InsStudentVo> res = new TableDataInfo<>();
        res.setRows(collect);
        res.setCode(HttpStatus.HTTP_OK);
        res.setMsg("查询成功");
        res.setTotal(result.getTotal());
        return res;
    }

    /**
     * 导师改变学生审核状态
     * @param stuId
     * @param insId
     * @param status
     */
    @Override
    @Transactional
    public void insExamine(Long stuId, Long insId,Long subId, Integer status) {
        Choose choose = new Choose();
        choose.setChooseStatus(status);
        choose.setInsConfirmDatetime(new Date());
        update(choose,new QueryWrapper<Choose>().eq("ins_id",insId).eq("stu_id",stuId));
        StudentDetail studentDetail = studentDetailService.getOne(new QueryWrapper<StudentDetail>().eq("stu_id", stuId));
        if (status==ChooseStatusConstants.CHOOSE_FAIL){
            //老师拒绝选择
            //修改招生名额表
            Spot spot = spotService.getOne(new QueryWrapper<Spot>().eq("sub_id", subId).eq("ins_id", insId));
            spot.setCheckedNumber(spot.getCheckedNumber()-1);
            spotService.updateById(spot);

            //发送确认邮箱
            if (studentDetail.getStuEmail()!=null){
                mailService.sendChooseFailMail(studentDetail.getStuEmail());
            }
        }else {
            if (studentDetail.getStuEmail()!=null){
                mailService.sendChooseSuccessMail(studentDetail.getStuEmail());
            }
        }

    }
}
